/**
 * 
 */
package com.googlecode.pcapj;

import java.net.Inet4Address;

/**
 * 
 */
 class IPv4PacketImpl extends PacketImpl implements IPv4Packet{
	private PacketFactory<? extends Packet> packetFactory;
	
	IPv4PacketImpl(byte[] buffer, int offset, int length) {
		super(buffer, offset, length);
	}
	void setPacketFactory(PacketFactory<? extends Packet> packetFactory) {
		this.packetFactory = packetFactory;
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.IPPacket#getVersion()
	 */
	public int getVersion() {
		return (0xf0 & binaryData.getByte(0)) >> 4;
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.IPPacket#getIHL()
	 */
	public int getIHL() {
		return 0x0f & binaryData.getByte(0);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.IPPacket#getTotalLength()
	 */
	public int getTotalLength() {
		return 0xffff & binaryData.getShort(2);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.IPPacket#getIdentification()
	 */
	public short getIdentification() {
		return binaryData.getShort(4);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.IPPacket#getProtocol()
	 */
	public byte getProtocol() {
		return binaryData.getByte(9);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.IPPacket#getSource()
	 */
	public Inet4Address getSource() {
		return (Inet4Address)binaryData.getInetAddress(12, 4);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.IPPacket#getDestination()
	 */
	public Inet4Address getDestination() {
		return (Inet4Address)binaryData.getInetAddress(16, 4);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.IPPacket#getOptionsData()
	 */
	public byte[] getOptions() {
		byte[] optionsData = new byte[0];
		int ihl  = getIHL();
		if(ihl >= 5){
			optionsData = binaryData.getBytes(20, ihl * 4 - 20);
		}
		return optionsData;
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.IPPacket#getProtocolData()
	 */
	public byte[] getData() {
		int headerSize = getIHL() * 4;
		return binaryData.getBytes(headerSize, getTotalLength() - headerSize);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.IPv4Packet#getTransportLayerPacket()
	 */
	public Packet getTransportLayerPacket() {
		Packet packet = null;
		int headerSize = getIHL() * 4;
		if(packetFactory != null){
			int offset = headerSize + binaryData.getOffset(); 
			packet = packetFactory.newPacket(
					binaryData.getBuffer(), 
					offset, 
					getTotalLength() - headerSize);
		}
		return packet;
	}
}
